package cn.wit.summit.chwan.utils;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.net.Uri;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.widget.ImageView;

import com.facebook.common.executors.CallerThreadExecutor;
import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.DataSource;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.controller.ControllerListener;
import com.facebook.drawee.drawable.ScalingUtils;
import com.facebook.drawee.generic.RoundingParams;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.drawee.view.SimpleDraweeView;
import com.facebook.imagepipeline.common.ResizeOptions;
import com.facebook.imagepipeline.core.ImagePipeline;
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.imagepipeline.image.ImageInfo;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;

import java.io.File;

import cn.wit.summit.chwan.R;

/**
 * Created by lala on 15/11/24.
 */
public class MyImageLoader {

    //region fresco

    public static void load(String src) {
        if (StringUtils.isNotEmpty(src) && src.startsWith("system_")) {
            src = UtilsMy.pareseSystemImage(src);
        }
        try {
            ImageRequest request = ImageRequest.fromUri(src);
            Fresco.getImagePipeline().prefetchToDiskCache(request, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void load(SimpleDraweeView view, String src) {
        if (StringUtils.isNotEmpty(src) && src.startsWith("system_")) {
            src = UtilsMy.pareseSystemImage(src);
        }
        load(view, R.drawable.main_normal_icon, src);
    }

    public static void load(SimpleDraweeView view, String src, ScalingUtils.ScaleType scaleType) {
        if (StringUtils.isNotEmpty(src) && src.startsWith("system_")) {
            src = UtilsMy.pareseSystemImage(src);
        }
        load(view, R.drawable.main_normal_icon, src, null, scaleType);
    }

    public static void load(SimpleDraweeView view, String src, RoundingParams roundingParams) {
        if (StringUtils.isNotEmpty(src) && src.startsWith("system_")) {
            src = UtilsMy.pareseSystemImage(src);
        }
        load(view, R.drawable.main_normal_icon, src, roundingParams, null);
    }

    public static void load(SimpleDraweeView view, int defRes, String src) {
        if (StringUtils.isNotEmpty(src) && src.startsWith("system_")) {
            src = UtilsMy.pareseSystemImage(src);
        }
        load(view, defRes, src, null, ScalingUtils.ScaleType.FIT_XY);
    }

    public static void load(SimpleDraweeView view, int defRes, String src, ScalingUtils.ScaleType scaleType) {
        if (StringUtils.isNotEmpty(src) && src.startsWith("system_")) {
            src = UtilsMy.pareseSystemImage(src);
        }
        load(view, defRes, src, null, scaleType);
    }

    public static void load(SimpleDraweeView view, int defRes, String src, RoundingParams roundingParams) {
        if (StringUtils.isNotEmpty(src) && src.startsWith("system_")) {
            src = UtilsMy.pareseSystemImage(src);
        }
        load(view, defRes, src, roundingParams, null);
    }
    public static void loadUserIcon(SimpleDraweeView view, int defRes, String src) {
        loadUserIcon(view, defRes, src, makeUserIconParams(view.getContext()), false);
    }
    public static RoundingParams makeUserIconParams(Context ctx) {
        Resources res    = ctx.getResources();
        float     radius = res.getDimension(R.dimen.wdp8);
        float     width  = res.getDimension(R.dimen.wdp1);
        int       color  = Color.parseColor("#b2b2b2");
        return new RoundingParams().setBorderWidth(width).setCornersRadius(radius).setBorderColor(color).setRoundAsCircle(true);
    }
    private static void loadUserIcon(SimpleDraweeView view, int defRes, String src, RoundingParams roundingParams, final boolean save4LocalUser) {
        if (view == null) return;
        final Context ctx = view.getContext();
        try {
            Resources res = ctx.getResources();

            if (defRes != 0) {
                Drawable drawable = res.getDrawable(defRes);
                if (drawable instanceof NinePatchDrawable || drawable instanceof ShapeDrawable) {
                    drawable = new BitmapDrawable(PictureUtil.drawableToBitmap(res.getDrawable(defRes)));
                }
                view.getHierarchy().setPlaceholderImage(drawable);
            }

            if (roundingParams != null) {
                view.getHierarchy().setRoundingParams(roundingParams);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (!loadUserIconCustom(view, defRes, src)) {
            try {

                ControllerListener controllerListener = new ControllerListener<ImageInfo>() {
                    @Override
                    public void onSubmit(String id, Object callerContext) {

                    }

                    @Override
                    public void onFinalImageSet(String id, ImageInfo imageInfo, Animatable animatable) {
//                        if (save4LocalUser)
//                            saveUserIcon(ctx, Uri.parse(id));
                    }

                    @Override
                    public void onIntermediateImageSet(String id, ImageInfo imageInfo) {

                    }

                    @Override
                    public void onIntermediateImageFailed(String id, Throwable throwable) {

                    }

                    @Override
                    public void onFailure(String id, Throwable throwable) {

                    }

                    @Override
                    public void onRelease(String id) {

                    }
                };

                DraweeController draweeController = Fresco.newDraweeControllerBuilder().setControllerListener(controllerListener)
                        .setUri(makeUri(src))
                        .build();
                view.setController(draweeController);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    public static boolean loadUserIconCustom(SimpleDraweeView view, int defRes, String src) {
        if (view == null) return false;
        boolean ret = false;
        try {
            final Context ctx = view.getContext();
            Resources     res = ctx.getResources();

            if (defRes != 0) {
                Drawable drawable = res.getDrawable(defRes);
                if (drawable instanceof NinePatchDrawable || drawable instanceof ShapeDrawable) {
                    drawable = new BitmapDrawable(PictureUtil.drawableToBitmap(res.getDrawable(defRes)));
                }
                view.getHierarchy().setPlaceholderImage(drawable);
            }

            ret = false;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return ret;
    }

    public static void load(SimpleDraweeView view, int defRes, String src, RoundingParams roundingParams, ScalingUtils.ScaleType scaleType) {
        if (StringUtils.isNotEmpty(src) && src.startsWith("system_")) {
            src = UtilsMy.pareseSystemImage(src);
        }
        if (view == null) return;
        final Context ctx = view.getContext();

        if (scaleType == null) {
            view.getHierarchy().setActualImageScaleType(ScalingUtils.ScaleType.FIT_XY);
        } else {
            view.getHierarchy().setActualImageScaleType(scaleType);
        }
//        if (defRes != 0) {
//            boolean placeholderRounded = false;
//            if (defRes == R.drawable.main_normal_icon && placeholderRounded) {
//                try {
//                    Bitmap bitmap = MyImageLoader.getInstance().getBitmapFromLruCache("main_normal_icon");
//                    if (bitmap == null) {
//                        Drawable drawable;
//                        drawable = view.getContext().getResources().getDrawable(defRes);
//                        if (drawable instanceof NinePatchDrawable || drawable instanceof ShapeDrawable) {
//                            bitmap = PictureUtil.drawableToBitmap(view.getContext().getResources().getDrawable(defRes));
//                            MyImageLoader.getInstance().addBitmap2LruCache("main_normal_icon", bitmap);
//                            drawable = new BitmapDrawable(bitmap);
//                        }
//                        view.getHierarchy().setPlaceholderImage(drawable);
//                    } else {
//                        view.getHierarchy().setPlaceholderImage(new BitmapDrawable(bitmap));
//                    }
//                } catch (Exception e) {
//                    e.printStackTrace();
//                    view.getHierarchy().setPlaceholderImage(defRes);
//                }
//            } else
//                view.getHierarchy().setPlaceholderImage(defRes);
//        }
        if (roundingParams != null) {
            view.getHierarchy().setRoundingParams(roundingParams);
        }
        try {
            view.setImageURI(makeUri(src));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //生成圆角图片
    public static Bitmap GetRoundedCornerBitmap(Bitmap bitmap, float roundPx) {
        try {
            Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                    bitmap.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas      canvas = new Canvas(output);
            final Paint paint  = new Paint();
            final Rect rect = new Rect(0, 0, bitmap.getWidth(),
                    bitmap.getHeight());
            final RectF rectF = new RectF(new Rect(0, 0, bitmap.getWidth(),
                    bitmap.getHeight()));
//            final float roundPx = 14;
            paint.setAntiAlias(true);
            canvas.drawARGB(0, 0, 0, 0);
            paint.setColor(Color.BLACK);
            canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

            final Rect src = new Rect(0, 0, bitmap.getWidth(),
                    bitmap.getHeight());

            canvas.drawBitmap(bitmap, src, rect, paint);
            return output;
        } catch (Exception e) {
            return bitmap;
        }
    }

    public static Bitmap rotateBitmap(Bitmap bitmap, int degrees) {
        if (degrees == 0 || null == bitmap) {
            return bitmap;
        }
        Matrix matrix = new Matrix();
        matrix.setRotate(degrees, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
        Bitmap bmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
//        if (null != bitmap) {
//            bitmap.recycle();
//        }
        return bmp;
    }

    public static void loadLiveScreen(final SimpleDraweeView view, String src, final float radios) {
//load(view,src);
        // To get image using Fresco
        ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(makeUri(src))
                .setProgressiveRenderingEnabled(true)
                //重新设置图片尺寸
                .setResizeOptions(new ResizeOptions(340, 200))
                .setAutoRotateEnabled(true)
                .build();
        ImagePipeline imagePipeline = Fresco.getImagePipeline();

        DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage(imageRequest, view.getContext());
        dataSource.subscribe(new BaseBitmapDataSubscriber() {
            @Override
            public void onNewResultImpl(@Nullable Bitmap bitmap) {
                // You can use the bitmap in only limited ways
                // No need to do any cleanup.

                if (bitmap == null) {
                } else {
                    final Bitmap b2 = GetRoundedCornerBitmap(rotateBitmap(bitmap, -90), radios);
                    if (Looper.getMainLooper() != Looper.myLooper()) {
                        view.post(new Runnable() {
                            @Override
                            public void run() {
                                view.setImageBitmap(b2);
                            }
                        });
                    } else {
                        view.setImageBitmap(b2);
                    }
                }
            }

            @Override
            public void onFailureImpl(DataSource dataSource) {
                // No cleanup required here.
            }
        }, CallerThreadExecutor.getInstance());

//            RotationOptions rotationOptions = RotationOptions.forceRotation(-90);
//            ImageRequest build = ImageRequestBuilder.newBuilderWithSource(makeUri(src))
//                    .setRotationOptions(rotationOptions)
//                    .build();
//            PipelineDraweeController controller = (PipelineDraweeController) Fresco.newDraweeControllerBuilder()
//                    .setImageRequest(build)
//                    .build();
//            mImageView.setController(controller);
    }

    public static void loadBitmapForImageView(final ImageView view, String src, final float radios) {
//load(view,src);
        // To get image using Fresco
        ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(makeUri(src))
                .setProgressiveRenderingEnabled(true)
                //重新设置图片尺寸
//                .setResizeOptions(new ResizeOptions(340, 200))
                .setAutoRotateEnabled(true)
                .build();
        ImagePipeline imagePipeline = Fresco.getImagePipeline();

        DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage(imageRequest, view.getContext());
        dataSource.subscribe(new BaseBitmapDataSubscriber() {
            @Override
            public void onNewResultImpl(@Nullable final Bitmap bitmap) {
                // You can use the bitmap in only limited ways
                // No need to do any cleanup.
                try {
                    if (bitmap == null) {
                    } else {
                        if (Looper.getMainLooper() != Looper.myLooper()) {
                            view.post(new Runnable() {
                                @Override
                                public void run() {
                                    view.setImageBitmap(bitmap);
                                }
                            });
                        } else {
                            view.setImageBitmap(bitmap);
                        }
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailureImpl(DataSource dataSource) {
                // No cleanup required here.
            }
        }, CallerThreadExecutor.getInstance());

//            RotationOptions rotationOptions = RotationOptions.forceRotation(-90);
//            ImageRequest build = ImageRequestBuilder.newBuilderWithSource(makeUri(src))
//                    .setRotationOptions(rotationOptions)
//                    .build();
//            PipelineDraweeController controller = (PipelineDraweeController) Fresco.newDraweeControllerBuilder()
//                    .setImageRequest(build)
//                    .build();
//            mImageView.setController(controller);
    }
    //endregion

    //region makeUri
    public static Uri makeUri(Context context, int resId) {
        String path = "res://" + context.getPackageName() + "/" + resId;
        return Uri.parse(path);
    }

    public static Uri makeUri(File file) {
        String path = "file://" + file;
        return Uri.parse(path);
    }

    public static Uri makeUri(String url) {
        return Uri.parse(StringUtils.getSafeString(url));
    }

//    public static Uri makeUri1(String asset) {
//        String path = "asset://" + asset;
//        return Uri.parse(path);
//    }
    //endregion


    //region RoundingParams
    public static RoundingParams makeRoundIconParams(Context ctx, int colorRes, int radioRes, int withRes) {
        Resources res    = ctx.getResources();
        float     radius = res.getDimension(radioRes);
        float     width  = res.getDimension(withRes);
        int       color  = res.getColor(colorRes);
        return new RoundingParams().setBorderWidth(width).setCornersRadius(radius).setBorderColor(color).setRoundAsCircle(true);
    }

    public static RoundingParams makeForumGameParams(Context ctx) {
        return makeRoundParams(ctx);
    }

    public static RoundingParams makeForumBannerParams(Context ctx) {
        return makeRoundParams(ctx);
    }

    public static RoundingParams makeForumIconParams(Context ctx) {
        return makeRoundParams(ctx);
    }

    public static RoundingParams makeRoundParams(Context ctx) {
        Resources res    = ctx.getResources();
        float     radius = res.getDimension(R.dimen.wdp8);
        return new RoundingParams().setCornersRadius(radius);
    }

    public static RoundingParams makeRoundParams(Context ctx, float radius) {
        return new RoundingParams().setCornersRadius(radius);
    }

//    public static RoundingParams makeCircleParams(Context ctx) {
//        return new RoundingParams().setRoundAsCircle(true);
//    }
    //endregion
    //endregion


    //    public static void loadLocalUserIcon(SimpleDraweeView view, int defRes, String src, RoundingParams roundingParams) {
//        if (view == null) return;
//
//        try {
//            String localIcon = AccountUtil_.getInstance_(view.getContext()).getLocalUserIcon();
//            File file = new File(localIcon);
//            if (StringUtils.isNotEmpty(localIcon) && file.exists()) {
//                Uri uri = makeUri(file);
//                src = uri.toString();
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//
//        loadUserIcon(view, defRes, src, roundingParams, true);
//    }

}
